package com.puzzle

import android.Manifest
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.text.TextUtils
import android.widget.Toast

import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.core.app.ActivityCompat
import androidx.core.net.toUri

import com.common.MessageBox
import com.puzzle.Game.Difficulty
import com.puzzle.Game.Status
import com.puzzle.ui.theme.PuzzleTheme

import java.io.File
import java.io.FileInputStream
import java.util.Objects

// 主活动
class MainActivity: ComponentActivity() {
    private lateinit var mGame: Game                // 游戏
    private lateinit var mMessageBox: MessageBox    // 消息窗口

    /**
     * 获取 URI 对应的文件路径(数据库表中的 _data 列)
     * @param uri           uri
     * @param selection     列
     * @param selectionArgs 列参数
     * @return 路径
     */
    private fun getDataColumn(uri: Uri, selection: String?, selectionArgs: Array<String>?): String {
        var path = ""
        val projection = arrayOf<String>(MediaStore.Images.Media.DATA)
        var cursor: Cursor? = null
        try {
            cursor = super.getContentResolver().query(uri, projection, selection, selectionArgs, null)
            if (cursor != null && cursor.moveToFirst()) {
                val columnIndex = cursor.getColumnIndexOrThrow(projection[0])
                path = cursor.getString(columnIndex)
            }
        } catch (_: Exception) {
            cursor?.close()
        }
        return path
    }

    /**
     * 从系统文件选择器返回的 uri 中获取文件路径。
     * @param context   设备环境
     * @param uri   系统文件选择器返回的 uri
     * @return uri 对应的文件路径
     */
    private fun getPathFromURI(context: Context, uri: Uri): String {
        var filePath = ""

        // 如果是文档类型的 URI
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // 通过 Document id 来进行处理
            val documentId = DocumentsContract.getDocumentId(uri)
            val authority = checkNotNull(uri.authority)

            if (authority == "com.android.providers.media.documents") {
                // 如果是本地图片
                // 使用':'分割
                val id = documentId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
                val selection = MediaStore.Images.Media._ID + "=?"
                val selectionArgs = arrayOf<String>(id)
                filePath = this.getDataColumn(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs)
            } else if (authority == "com.android.providers.downloads.documents") {
                // 如果是网络图片
                val tempUri = "content://downloads/public_downloads".toUri()
                val contentUri = ContentUris.withAppendedId(tempUri, documentId.toLong())
                filePath = this.getDataColumn(contentUri, null, null)
            }
        } else if (Objects.requireNonNull<String?>(uri.scheme).equals("content", true)) {
            // 如果是内容类型的 URI
            filePath = this.getDataColumn(uri, null, null)
        } else if (uri.scheme.equals("file", true)) {
            // 如果是文件类型的 URI
            filePath = uri.path.toString()
        }
        return filePath
    }

    /**
     * 界面布局。
     */
    @Composable
    fun Greeting() {
        ConstraintLayout(Modifier
            .fillMaxSize()
            .systemBarsPadding()
        ) {
            var showMenu by remember {
                mutableStateOf(false)
            }
            var showDifficultyMenu by remember {
                mutableStateOf(false)
            }
            var showBorderMenu by remember {
               mutableStateOf(false)
            }
            val (button) = this.createRefs()

            // 消息窗口
            mMessageBox.Greeting()

            // 游戏区域
            mGame.GameBoard()

            // 按钮
            Button(
                onClick = {
                    showMenu = true
                },
                modifier = Modifier
                    .size(Const.BUTTON_SIZE)
                    .constrainAs(button) {
                        end.linkTo(parent.end)
                        bottom.linkTo(parent.bottom)
                    },
                colors = ButtonDefaults.buttonColors(Color.Transparent)
            ) {}

            val menuPosition = DpOffset(LocalConfiguration.current.screenWidthDp.dp, 0.dp)
            // 主菜单
            DropdownMenu(
                expanded = showMenu,
                offset = menuPosition,
                onDismissRequest = {
                    showMenu = false
                }
            ) {
                // "开始"菜单项
                DropdownMenuItem(
                    text = {
                        Text(super.getString(R.string.IDS_START))
                    },
                    onClick = {
                        showMenu = false
                        this@MainActivity.onMenuItemStartClicked()
                    }
                )
                // "难度"菜单项
                DropdownMenuItem(
                    text = {
                        Text(super.getString(R.string.IDS_SET_DIFFICULTY))
                    },
                    onClick = {
                        showMenu = false
                        showDifficultyMenu = true
                    }
                )
                // "图片边框"菜单项
                DropdownMenuItem(
                    text = {
                        Text(super.getString(R.string.IDS_SET_BORDER))
                    },
                    onClick = {
                        showMenu = false
                        showBorderMenu = true
                    }
                )
                // "换图片"菜单项
                DropdownMenuItem(
                    text = {
                        Text(super.getString(R.string.IDS_SET_PICTURE))
                    },
                    onClick = {
                        showMenu = false
                        this@MainActivity.onMenuItemSetPictureClicked()
                    }
                )
            }

            // 难度菜单
            DropdownMenu(
                expanded = showDifficultyMenu,
                offset = menuPosition,
                onDismissRequest = {
                    showDifficultyMenu = false
                }
            ) {
                DropdownMenuItem(
                    text = {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(mGame.difficulty == Difficulty.EASY, null)
                            Text(super.getString(R.string.IDS_EASY))
                        }
                    },
                    onClick = {
                        showDifficultyMenu = false
                        this@MainActivity.onMenuItemSetDifficultyClicked(Difficulty.EASY)
                    }
                )
                DropdownMenuItem(
                    text = {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(mGame.difficulty == Difficulty.MEDIUM, null)
                            Text(super.getString(R.string.IDS_MEDIUM))
                        }
                    },
                    onClick = {
                        showDifficultyMenu = false
                        this@MainActivity.onMenuItemSetDifficultyClicked(Difficulty.MEDIUM)
                    }
                )
                DropdownMenuItem(
                    text = {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(mGame.difficulty == Difficulty.HARD, null)
                            Text(super.getString(R.string.IDS_HARD))
                        }
                    },
                    onClick = {
                        showDifficultyMenu = false
                        this@MainActivity.onMenuItemSetDifficultyClicked(Difficulty.HARD)
                    }
                )
            }

            // "图片边框"菜单
            DropdownMenu(
                expanded = showBorderMenu,
                offset = menuPosition,
                onDismissRequest = {
                    showBorderMenu = false
                }
            ) {
                DropdownMenuItem(
                    text = {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(mGame.pictureHasBorder, null)
                            Text(super.getString(R.string.IDS_HAS_BORDER))
                        }
                    },
                    onClick = {
                        showBorderMenu = false
                        this@MainActivity.onMenuItemSetBorderClicked(true)
                    }
                )
                DropdownMenuItem(
                    text = {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(!mGame.pictureHasBorder, null)
                            Text(super.getString(R.string.IDS_NO_BORDER))
                        }
                    },
                    onClick = {
                        showBorderMenu = false
                        this@MainActivity.onMenuItemSetBorderClicked(false)
                    }
                )
            }
        }

        // 吐司窗口
        if (mGame.status == Status.WON) {
            Toast.makeText(this@MainActivity, super.getString(R.string.IDS_WON), Toast.LENGTH_LONG).show()
        }
    }

    /**
     * Activity 返回结果事件的响应方法。
     * @param requestCode   请求码
     * @param resultCode    结果码
     * @param data          数据
     */
    @Deprecated("Deprecated in Java")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode != RESULT_OK || data == null) {
            return
        }

        // 加载图片
        val filePath = this.getPathFromURI(this, data.data!!)
        if (TextUtils.isEmpty(filePath)) {
            Toast.makeText(this, R.string.IDS_NOT_SUPPORT_IMAGE, Toast.LENGTH_LONG).show()
            return
        }

        val file = File(filePath)
        var image: Bitmap? = null
        try {
            val fileInputStream = FileInputStream(file)
            image = BitmapFactory.decodeStream(fileInputStream)
            fileInputStream.close()
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }

        if (image == null) {
            Toast.makeText(this, R.string.IDS_NOT_SUPPORT_IMAGE, Toast.LENGTH_LONG).show()
            return
        }

        // 设置图片
        mGame.setPicture(image)

        super.onActivityResult(requestCode, resultCode, data)
    }

    /**
     * 创建事件的响应方法。
     * @param savedInstanceState    保存的实例状态
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.enableEdgeToEdge()

        // 请求读 SD 卡的权限
        val permissionStorage = arrayOf<String?>(Manifest.permission.READ_EXTERNAL_STORAGE)
        ActivityCompat.requestPermissions(this, permissionStorage, 1)

        // 初始化成员
        mGame = Game(resources)
        mMessageBox = MessageBox()

        // 设置内容
        this.setContent {
            PuzzleTheme {
                this.Greeting()
            }
        }

        // 弹出提示
        Toast.makeText(this, R.string.IDS_TIP_TEXT, Toast.LENGTH_LONG).show()
    }

    /**
     * "图片边框"菜单项的单击响应方法。
     * @param hasBorder 有边框则为 true，否则为 false
     */
    private fun onMenuItemSetBorderClicked(hasBorder: Boolean) {
        // 如果要设置的参数与当前游戏参数相同，则直接返回
        if (hasBorder == mGame.pictureHasBorder) {
            return
        }

        // 设置边框
        mGame.pictureHasBorder = hasBorder
    }

    /**
     * "难度"菜单项的单击响应方法。
     * @param diff  难度
     */
    private fun onMenuItemSetDifficultyClicked(diff: Difficulty) {
        if (diff == mGame.difficulty) {
            return
        }

        if (mGame.status != Status.END) {
            // 弹出询问对话框
            mMessageBox.show(
                cancelButtonText = super.getString(android.R.string.cancel),
                okButtonText = super.getString(android.R.string.ok),
                onOK = {
                    // 设置难度
                    mGame.difficulty = diff
                },
                tipText = super.getString(R.string.IDS_RESET)
            )
        } else {
            mGame.difficulty = diff
        }
    }

    /**
     * "换图片"菜单项的单击响应方法。
     */
    private fun onMenuItemSetPictureClicked() {
        if (mGame.status != Status.END) {
            // 弹出询问对话框
            mMessageBox.show(
                cancelButtonText = super.getString(android.R.string.cancel),
                okButtonText = super.getString(android.R.string.ok),
                onOK = {
                    this@MainActivity.setPicture()
                },
                tipText = super.getString(R.string.IDS_RESET)
            )
        } else {
            this.setPicture()
        }
    }

    /**
     * "开始"菜单项的单击响应方法。
     */
    private fun onMenuItemStartClicked() {
        mGame.start()
    }

    /**
     * 设置图片。
     */
    private fun setPicture() {
        // 调用系统自带的文件管理器
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        intent.setType("image/*")
        intent.addCategory(Intent.CATEGORY_OPENABLE)
        super.startActivityForResult(intent, 1)
    }
}
